/*
 * MainGameController.h
 *
 *  Created on: Dec 27, 2011
 *      Author: rudi
 */

#ifndef MAINGAMECONTROLLER_H_
#define MAINGAMECONTROLLER_H_
#include <wx/wx.h>
#include "IGameController.h"
#include "SmartPointer.h"
#include "IGameStateController.h"
#include "WxUtils.h"

class MainPanel;
class wxSocketEvent;

/**
 * This class handles the events during the whole life of the application
 *
 * @see IGameController
 * @author Rudolf Heszele heszele@gmail.com
 * @version 1.0
 * @since 2012-03-08
 */
class MainGameController: public IGameController, public wxEvtHandler
{
	public:
		/**
		 * Helper class to change the State of the MainGameController object
		 *
		 * This class instructs wxWidgets to do an async callback, and in this async callback
		 * it changes the State of the MainGameController object
		 * @see WxUtils::ITask
		 */
		class ChangeStateTask: public WxUtils::ITask
		{
			public:
				/**
				 * The only constructor takes the needed parameters to perform the state change
				 *
				 * @param gameStartedController The object to perform the state change on
				 * @param subStateController The new SubState, which needs to be set
				 */
				ChangeStateTask(MainGameController* mainGameController, SmartPointer<IGameStateController> gameStateController);
				virtual ~ChangeStateTask();
				/**
				 * @see WxUtils::ITask::execute
				 */
				virtual void execute();

			private:
				MainGameController* mMainGameController;
				SmartPointer<IGameStateController> mGameStateController;
		};
		/**
		 * Make the class friend, to reach the private data members
		 */
		friend class ChangeStateTask;
		/**
		 * The default constructor can optionally take an argument
		 *
		 * The optionally argument is taken only when the application is started, because in this case the MainPanel can not be reached through
		 * the wxGetApp method, since the window itself is not constructed yet by the wxWidgets
		 * @param mainPanel The pointer to the MainPanel placed on the window
		 */
		MainGameController(MainPanel* mainPanel = NULL);
		virtual ~MainGameController();

		// Methods inherited from Controller

		/**
		 * @see IController::handleMouseDown
		 */
		virtual void handleMouseDown(const wxPoint& position);
		/**
		 * @see IController::handleMouseUp
		 */
		virtual void handleMouseUp(const wxPoint& position);
		/**
		 * @see IController::handleMouseMotion
		 */
		virtual bool handleMouseMotion(const wxPoint& position);
		/**
		 * @see IController::getBitmapToPaint
		 */
		virtual const wxBitmap& getBitmapToPaint() const;
		/**
		 * @see IController::getBitmapToDraw
		 */
		virtual wxBitmap& getBitmapToDraw();

		// Methods inherited from IGameController

		/**
		 * @see IGameController::host
		 */
		virtual bool host(const wxString& level);
		/**
		 * @see IGameController::join
		 */
		virtual bool join(const wxString& host, int port);
		/**
		 * @see IGameController::configurationChange
		 */
		virtual void configurationChange();
		/**
		 * @see IGameController::kickOffClient
		 */
		virtual void kickOffClient();
		/**
		 * @see IGameController::finish
		 */
		virtual void finish(IGameController::FinishReason finishReason);
		/**
		 * @see IGameController::changeState
		 */
		virtual void changeState(IGameStateController* gameStateController);

	private:
		/**
		 * This method is called by the wxWidgets if any socket related event happened
		 *
		 * @param socketEvent The object created by wxWidgets, holding informations about the event and the socket
		 */
		void handleSocketEvent(wxSocketEvent& socketEvent);

		/**
		 * The actual state of the game. Every event is forwarded to this object
		 */
		SmartPointer<IGameStateController> mGameStateController;

		DECLARE_EVENT_TABLE()
};

#endif /* MAINGAMECONTROLLER_H_ */
